#ifndef __CACHE_H__
#define __CACHE_H__

#include "common.h"

/* L1 Cache parameters per PA3 Stage1 */
#define L1_BLOCK_SIZE   64u
#define L1_BLOCK_MASK   (L1_BLOCK_SIZE - 1)
#define L1_WAYS         8u
#define L1_SETS         128u
#define L1_SET_MASK     (L1_SETS - 1)
#define L1_OFFSET_BITS  6u
#define L1_INDEX_BITS   7u

typedef struct {
    uint8_t data[L1_BLOCK_SIZE];
    uint32_t tag;
    uint8_t valid; /* 0 or 1 */
} cache_line_t;

typedef struct {
    cache_line_t ways[L1_WAYS];
} cache_set_t;

typedef struct {
    cache_set_t sets[L1_SETS];
    uint32_t rng_state;
} l1_cache_t;

void cache_init(void);
uint32_t cache_read(hwaddr_t addr, size_t len);
void cache_write(hwaddr_t addr, size_t len, uint32_t data);

/* Optional statistics */
void cache_stats_dump(void);
void cache_stats_reset(void);

#endif

